package cn.buk.tms.eotms.security;

import cn.buk.common.util.DateUtil;
import cn.buk.jedis.RedisDao;
import cn.buk.tms.eotms.dto.DtoLoginStatus;
import com.alibaba.fastjson.JSON;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.filter.GenericFilterBean;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;

import static cn.buk.tms.eotms.config.SecurityConfiguration.passwordEncoder;
import static cn.buk.tms.eotms.security.LoginUtil.execLoginProcess;
import static java.nio.charset.StandardCharsets.UTF_8;

/**
 *
 * @author yfdai
 * @date 2017/1/6
 */
public class MySessionManagementFilter extends GenericFilterBean {

    private static final Logger logger = LogManager.getLogger(MySessionManagementFilter.class);

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisDao redisDao;

    public MySessionManagementFilter() {

    }

    @Override
    public void doFilter(
        ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;

        Object obj = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
        if (obj == null) {
            autoLogin(request);
        }

        chain.doFilter(req, res);
    }

    /**
     * 通过cookie中的token值处理自动登录
     */
    private void autoLogin(HttpServletRequest request) {
        String token = null;

        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if ("token".equalsIgnoreCase(cookies[i].getName())) {
                    token = cookies[i].getValue();
                    if (token != null) {
                        logger.info("token in cookies: " + token);
                    }
                }
            }
        }

        if (token == null) {
            token = request.getParameter("token");
            if (token != null) {
                logger.info("token in params: " + token);
            }
        }
        if (token == null) {
            token = request.getHeader("token");
            if (token != null) {
//                logger.info("token in headers: " + token);
            }
        }

        HttpSession session = request.getSession();

        if (token != null) {
            byte[] bytes = redisDao.get("token:" + token);
            if (bytes != null && bytes.length > 0) {
                String temp = new String(bytes, UTF_8);

                DtoLoginStatus dto = JSON.parseObject(temp, DtoLoginStatus.class);
                try {

                    logger.info("{}, {}.", dto.getUsername(), dto.getPassword());
                    execLoginProcess(authenticationManager, session, dto.getUserId(), dto.getEnterpriseId(), dto.getUsername(), dto.getPassword(), dto.getFullName());
                    logger.info(dto.getUserId() + ", " + dto.getUsername() + ": auto login at " + DateUtil.getCurDateTime() + " by token " + token + ".");
                } catch (AuthenticationException ex) {
                    logger.warn(ex.getMessage());
                }
            }
        }
    }
}
